package com.sky.his.api.report;

import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import org.apache.poi.util.Units;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: WangJiYou
 * @Date: 2024/12/18/13:40
 * @Description:
 */
@Component
public class CheckupReportUtil {

    private void createCover(XWPFDocument doc, HashMap param) throws Exception {
        // 创建一个段落
        XWPFParagraph paragraph = doc.createParagraph();

        // 创建一个运行并设置字体属性
        XWPFRun run = paragraph.createRun();
        run.setBold(true);  // 设置字体加粗
        run.setFontSize(20);  // 设置字体大小
        run.setFontFamily("Microsoft YaHei");  // 设置字体为微软雅黑
        run.setUnderline(UnderlinePatterns.THICK);  // 设置带有下划线
        run.setText("北京市神州大健康体检中心");  // 设置文本

        // 设置行间距
        CTP ctp = paragraph.getCTP();  // 获取段落的CTP（XML表示形式）
        CTPPr ctpPr = ctp.addNewPPr();  // 获取段落的属性（PPr）
        CTSpacing ctSpacing = ctpPr.addNewSpacing();  // 设置行间距
        ctSpacing.setLineRule(STLineSpacingRule.EXACT);  // 设置精确行间距
        ctSpacing.setLine(BigInteger.valueOf(480));  // 设置行间距的值，单位是磅（1磅=20个单位）

        // 创建一个新的运行并设置字体属性
        paragraph = doc.createParagraph();
        run = paragraph.createRun();
        run.setFontSize(10);  // 设置字体大小为10磅
        run.setFontFamily("Microsoft YaHei");  // 设置字体为微软雅黑
        run.setText("Beijing Shenzhou Grand Health Examination Center");  // 设置段落文本

        // 设置行间距
        ctp = paragraph.getCTP();  // 获取段落的CTP（XML表示形式）
        ctpPr = ctp.addNewPPr();  // 获取段落属性（PPr）
        ctSpacing = ctpPr.addNewSpacing();  // 设置行间距
        ctSpacing.setLineRule(STLineSpacingRule.EXACT);  // 设置行间距为精确值
        ctSpacing.setLine(BigInteger.valueOf(280));  // 设置行间距为280个单位（单位是磅）


        // 创建一个新的段落
        paragraph = doc.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // 设置段落居中对齐

        // 创建一个新的运行并设置字体样式
        run = paragraph.createRun();
        run.setBold(true);  // 设置字体加粗
        run.setFontSize(26);  // 设置字体大小为26磅
        run.setFontFamily("Microsoft YaHei");  // 设置字体为微软雅黑
        run.setText("体检报告书");  // 设置文本内容

        // 设置段落上下间距（类似 CSS 中的上下外填充）
        ctp = paragraph.getCTP();  // 获取段落的CTP（XML表示形式）
        ctpPr = ctp.addNewPPr();  // 获取段落的属性（PPr）
        ctSpacing = ctpPr.addNewSpacing();  // 设置行间距
        ctSpacing.setBeforeLines(BigInteger.valueOf(800));  // 设置段落前的间距，单位是1/20磅（80磅）
        ctSpacing.setAfterLines(BigInteger.valueOf(800));  // 设置段落后的间距，单位是1/20磅（80磅）

        // 构造二维码配置
        QrConfig qrConfig = new QrConfig();
        qrConfig.setWidth(150);
        qrConfig.setHeight(150);
        qrConfig.setMargin(2);

        // 获取 UUID 参数
        String uuid = "01GWY35Z8X101682HXM7H4405日";  // 这里假设获取 UUID 参数

        // 生成二维码图片对象
        BufferedImage bufferedImage = QrCodeUtil.generate(uuid, qrConfig);

        // 将二维码图片写入输出流
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", bout);  // 使用 png 格式保存二维码图像

        // 将输出流转换为输入流
        InputStream input = new ByteArrayInputStream(bout.toByteArray());


        // 创建一个新的段落并设置居中对齐
        paragraph = doc.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // 图片居中对齐

        // 设置图片下方外填充（段落间距）
        ctp = paragraph.getCTP();
        ctpPr = ctp.addNewPPr();
        ctSpacing = ctpPr.addNewSpacing();
        ctSpacing.setAfterLines(BigInteger.valueOf(40));  // 设置段落下方的间距（相当于外填充）

        // 创建运行对象并插入图片
        run = paragraph.createRun();
        run.addPicture(input, XWPFDocument.PICTURE_TYPE_JPEG, "barcode.jpg",
                Units.toEMU(bufferedImage.getWidth()), Units.toEMU(bufferedImage.getHeight()));

        // 创建一个 4 行 2 列的表格
        XWPFTable table = doc.createTable(4, 2);

        // 设置表格水平居中
        table.setTableAlignment(TableRowAlign.CENTER);

        // 取消表格边框
        table.getCTTbl().getTblPr().unsetTblBorders();

        // 获取静态数据
        ArrayList<HashMap> list = (ArrayList) param.get("item");

        // 循环填充表格数据
        for (int i = 0; i < list.size(); i++) {
            HashMap<String, String> map = list.get(i);
            String label = map.get("label");
            String value = map.get("value");

            // 获取当前行
            XWPFTableRow row = table.getRow(i);
            row.setHeight(600); // 设置行高

            // 获取当前行的所有单元格
            List<XWPFTableCell> tableCells = row.getTableCells();

            // 设置第二列单元格宽度
            CTTcPr ctTcPr = tableCells.get(1).getCTTc().addNewTcPr();
            CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
            ctTblWidth.setW(BigInteger.valueOf(2800)); // 设置宽度

            // 设置当前行第一个单元格内容
            paragraph = tableCells.get(0).getParagraphArray(0);
            run = paragraph.createRun();
            run.setFontFamily("Microsoft YaHei");
            run.setText(label);

            // 设置当前行第二个单元格内容
            paragraph = tableCells.get(1).getParagraphArray(0);
            run = paragraph.createRun();
            run.setFontFamily("Microsoft YaHei");
            run.setText("   " + value);
        }

    }

    private void createWelcome(XWPFDocument doc, HashMap param) {

        // 创建一个新的段落并设置居中对齐
        XWPFParagraph paragraph = doc.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // 设置居中对齐

        // 创建一个新的运行对象
        XWPFRun run = paragraph.createRun();
        run.setFontSize(18);  // 设置字体大小
        run.setFontFamily("Microsoft YaHei");  // 设置字体
        run.setText("健康体检报告");  // 设置文本内容

        // 设置行间距和段落间距
        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.addNewPPr();
        CTSpacing ctSpacing = ctpPr.addNewSpacing();  // 设置行间距

        ctSpacing.setLineRule(STLineSpacingRule.EXACT);  // 设置行间距规则为精确值
        ctSpacing.setLine(BigInteger.valueOf(420));  // 设置行间距为420（单位是磅）

        // 设置上外填充，实现另起一页
        ctSpacing.setBeforeLines(BigInteger.valueOf(200));  // 设置段落前的外间距
        ctSpacing.setAfterLines(BigInteger.valueOf(200));  // 设置段落后的外间距

        // 创建一个新的段落
        paragraph = doc.createParagraph();

        // 创建一个新的运行对象
        run = paragraph.createRun();
        run.setFontSize(10); // 设置字体大小为 10
        run.setFontFamily("Microsoft YaHei"); // 设置字体为 Microsoft YaHei

        // 根据性别设置称呼
        String name = MapUtil.getStr(param, "name");
        String sex = MapUtil.getStr(param, "sex");
        String tempName = name + (sex.equals("男") ? "先生" : "女士");

        // 设置文本内容
        run.setText("尊敬的 " + tempName + "，您好!");

        // 设置行间距和段落间距
        ctp = paragraph.getCTP();
        ctpPr = ctp.addNewPPr();
        ctSpacing = ctpPr.addNewSpacing();  // 设置行间距

        ctSpacing.setLineRule(STLineSpacingRule.EXACT);  // 设置行间距为精确值
        ctSpacing.setLine(BigInteger.valueOf(380));  // 设置行间距为 380 磅
        ctSpacing.setAfterLines(BigInteger.valueOf(50));  // 设置段落后间距为 50 磅


        // 创建第二行文字的段落
        paragraph = doc.createParagraph();

        // 设置段首缩进两个汉字（大约是 600 英文单位）
        paragraph.setIndentationFirstLine(600);  // 设置段落首行缩进

        // 创建一个新的运行对象
        run = paragraph.createRun();
        run.setFontSize(10);  // 设置字体大小为 10
        run.setFontFamily("Microsoft YaHei");  // 设置字体为 Microsoft YaHei

        // 设置文本内容
        run.setText("感谢您到北京市神州大健康中心体检，现将您的体检结果汇总如下，请您认真阅读体检结果和建议。如有疑问，请您来我院或者致电本中心服务电话 010-24813397，我们将安排专业人员为您答疑解惑。欢迎对我们的工作提出批评和建议，祝您健康!");

        // 设置行间距和段落间距
        ctp = paragraph.getCTP();
        ctpPr = ctp.addNewPPr();
        ctSpacing = ctpPr.addNewSpacing();  // 设置行间距

        ctSpacing.setLineRule(STLineSpacingRule.EXACT);  // 设置行间距为精确值
        ctSpacing.setLine(BigInteger.valueOf(380));  // 设置行间距为 380 磅
        ctSpacing.setAfterLines(BigInteger.valueOf(100));  // 设置段落后间距为 100 磅
    }

    private void createCheckup(XWPFDocument doc, List<Map> list) {
        // 创建第三行文字的段落
        XWPFParagraph paragraph = doc.createParagraph();

        // 创建一个新的运行对象
        XWPFRun run = paragraph.createRun();
        run.setFontSize(14);  // 设置字体大小为 14
        run.setFontFamily("Microsoft YaHei");  // 设置字体为 Microsoft YaHei
        run.setText("体检项目");  // 设置文本内容

        // 设置段落的上下外填充（段落前后间距）
        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.addNewPPr();
        CTSpacing ctSpacing = ctpPr.addNewSpacing();  // 设置段落的外填充

        // 设置段落前间距
        ctSpacing.setBeforeLines(BigInteger.valueOf(200));  // 设置段落前外填充为 200 磅

        // 设置段落后间距
        ctSpacing.setAfterLines(BigInteger.valueOf(100));  // 设置段落后外填充为 100 磅

        // 获取表格属性并设置宽度
        XWPFTable table = doc.createTable(list.size() + 1, 3);
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        tblPr.getTblW().setType(STTblWidth.DXA);  // 设置表格宽度类型为 DXA（即以 1/1440 英寸为单位）
        tblPr.getTblW().setW(BigInteger.valueOf(9850));  // 设置表格宽度为 9850 DXA（即宽度）

        String[] array = {
                "序号",
                "体检科室",
                "体检内容"
        };

        XWPFTableRow row = table.getRow(0);
        row.setHeight(550);
        // 获取当前行的所有单元格
        List<XWPFTableCell> tableCells = row.getTableCells();

        // 遍历表头内容并设置每个单元格的文本
        for (int i = 0; i < array.length; i++) {
            String text = array[i];  // 获取表头文字

            // 获取表格单元格
            XWPFTableCell cell = tableCells.get(i);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // 垂直居中
            cell.setColor("f0f0f0");  // 设置背景颜色（灰色）

            // 获取当前单元格的段落并设置对齐方式
            paragraph = cell.getParagraphArray(0);  // 获取第一个段落
            paragraph.setAlignment(ParagraphAlignment.CENTER);  // 设置段落居中对齐

            // 创建并设置字体样式
            run = paragraph.createRun();
            run.setFontSize(9);  // 设置字体大小
            run.setFontFamily("Microsoft YaHei");  // 设置字体为微软雅黑
            run.setText(text);  // 设置单元格的文本
        }
        String temp = null;
        int index = 0;
        for (int i = 0; i < list.size(); i++) {
            Map one = list.get(i);
            String place = MapUtil.getStr(one, "place");
            String item = MapUtil.getStr(one, "item");

            // 获取当前行，跳过表头行
            row = table.getRow(i + 1);  // 获取当前行
            row.setHeight(550);  // 设置行高

            tableCells = row.getTableCells();

            XWPFTableCell cell = tableCells.get(1);
            STMerge.Enum val = null;
            if (!place.equals(temp)) {
                index++;
                temp = place;  // Update temp with the current 'place'
                // Merge the current cell (normal display)
                val = STMerge.RESTART;  // Indicating a new group of cells
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
            } else {
                // Continue merging with the previous cell
                val = STMerge.CONTINUE;  // Continuing the vertical merge with the previous cell
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
            }
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            paragraph = cell.getParagraphArray(0);
            paragraph.setAlignment(ParagraphAlignment.CENTER);
            run = paragraph.createRun();
            run.setFontSize(9);
            run.setFontFamily("Microsoft YaHei");
            run.setText(place);

            cell = tableCells.get(0);
            cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            paragraph = (cell.getParagraphArray(0) != null) ? cell.getParagraphArray(0) : cell.addParagraph();
            paragraph.setAlignment(ParagraphAlignment.CENTER);
            run = paragraph.createRun();
            run.setFontSize(9);
            run.setFontFamily("Microsoft YaHei");
            run.setText(index + "");

            cell = tableCells.get(2);  // Use 'cell' instead of 'cel1'
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            paragraph = (cell.getParagraphArray(0) != null) ? cell.getParagraphArray(0) : cell.addParagraph();

            paragraph.setAlignment(ParagraphAlignment.CENTER);
            run = paragraph.createRun();
            run.setFontSize(9);  // Set font size
            run.setFontFamily("Microsoft YaHei");  // Set font family
            run.setText(item);  // Set the item text
        }

    }

    private void createCheckupResultByTemplate_1(XWPFDocument doc, Map param) throws Exception {
        String place = MapUtil.getStr(param, "place");
        List<Map> item = MapUtil.get(param, "item", List.class);
        String doctor = MapUtil.getStr(param, "doctorName");
        String date = MapUtil.getStr(param, "date");

        XWPFParagraph paragraph = doc.createParagraph();
        paragraph.setBorderBottom(Borders.BABY_PACIFIER);

        XWPFRun run = paragraph.createRun();
        run.setFontSize(14);
        run.setFontFamily("Microsoft YaHei");
        run.setTextHighlightColor("lightGray");
        run.setText("【" + place + "体检结果】");

        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.addNewPPr();
        CTSpacing ctSpacing = ctpPr.addNewSpacing();
        ctSpacing.setBeforeLines(BigInteger.valueOf(250));
        ctSpacing.setAfterLines(BigInteger.valueOf(150));

        XWPFTable table = doc.createTable(item.size() + 1, 5);
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        tblPr.getTblW().setType(STTblWidth.DXA);
        tblPr.getTblW().setW(BigInteger.valueOf(9850));

        XWPFTableRow row = table.getRow(0);
        row.setHeight(500);  // Set height for header row
        List<XWPFTableCell> tableCells = row.getTableCells();
        String[] array = {
                "序号#800",
                "检查项目#2200",
                "检查结果#3000",
                "单位#1200",
                "参考值#1300",
        };

        for (int i = 0; i <= 4; i++) {
            XWPFTableCell cell = tableCells.get(i);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell.setColor("f0f0f0");

            paragraph = cell.getParagraphArray(0);

            if (i != 2) {
                paragraph.setAlignment(ParagraphAlignment.CENTER);
            } else {
                paragraph.setIndentationLeft(200);
            }

            run = paragraph.createRun();
            run.setFontSize(9);
            run.setFontFamily("Microsoft YaHei");

            String label = array[i].split("#")[0];
            int width = Integer.parseInt(array[i].split("#")[1]);
            run.setText(label);

            CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
            CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
            ctTblWidth.setW(BigInteger.valueOf(width));
        }
        for (int i = 0; i < item.size(); i++) {
            Map map = item.get(i);

            String name = MapUtil.getStr(map, "name");
            String value = MapUtil.getStr(map, "value");
            String unit = MapUtil.getStr(map, "unit");
            unit = (unit == null) ? "" : unit;
            String standard = MapUtil.getStr(map, "standard");
            standard = (standard == null) ? "" : standard;
            String[] temp = {
                    i + 1 + "",
                    name,
                    value,
                    unit,
                    standard
            };

            row = table.getRow(i + 1);
            row.setHeight(500);
            tableCells = row.getTableCells();

            for (int j = 0; j < temp.length; j++) {
                XWPFTableCell cell = tableCells.get(j);
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);

                paragraph = cell.getParagraphArray(0);

                if (j != 2) {
                    paragraph.setAlignment(ParagraphAlignment.CENTER);
                } else {
                    paragraph.setIndentationLeft(200);
                }

                run = paragraph.createRun();
                run.setFontSize(9);
                run.setFontFamily("Microsoft YaHei");
                run.setText(temp[j]);
            }
        }
        paragraph = doc.createParagraph();
        run = paragraph.createRun();
        run.setFontSize(9);
        run.setFontFamily("Microsoft YaHei");
        run.setText("体检医生: " + doctor + "\t\t\t\t\t\t\t日期: " + date);

        ctp = paragraph.getCTP();
        ctpPr = ctp.addNewPPr();
        ctSpacing = ctpPr.addNewSpacing();
        ctSpacing.setBeforeLines(BigInteger.valueOf(100));
        ctSpacing.setAfterLines(BigInteger.valueOf(150));
    }

    private void createCheckupResultByTemplate_2(XWPFDocument doc, Map param) throws Exception {
        String place = MapUtil.getStr(param, "place");
        List<Map> item = (List<Map>) param.get("item");
        String doctor = MapUtil.getStr(param, "doctor");
        String date = MapUtil.getStr(param, "date");
        String image = MapUtil.getStr(param, "image");

        XWPFParagraph paragraph = doc.createParagraph();
        paragraph.setBorderBottom(Borders.BABY_RATTLE);  // 确保边框类型正确，'BABY_RATTLE' 是正确的常量名称

        XWPFRun run = paragraph.createRun();
        run.setFontSize(14);
        run.setFontFamily("Microsoft YaHei");
        run.setTextHighlightColor("lightGray");
        run.setText("【" + place + "体检结果】");

        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.addNewPPr();
        CTSpacing ctSpacing = ctpPr.addNewSpacing();  // 这里应该是正确的创建 CTSpacing 的方式
        // 处理段落间距设置
        ctSpacing.setBeforeLines(BigInteger.valueOf(250));  // 使用 BigInteger.valueOf 来生成 BigInteger 数字
        ctSpacing.setAfterLines(BigInteger.valueOf(150));

        if (image != null) {  // 确保图片链接不为空
            URL url = new URL(image);
            InputStream in = url.openStream();
            BufferedImage bufferedImage = ImageIO.read(in);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();

            // 调整图片尺寸适配宽度
            double scaling = 1.0;
            if (width > 72 * 9.13) {
                scaling = (72.0 * 9.13) / width;
            }

            // 创建段落来插入图片
            paragraph = doc.createParagraph();
            paragraph.setAlignment(ParagraphAlignment.LEFT);  // 设置图片左对齐

            // 获取 CTP（XML 标记）
            ctp = paragraph.getCTP();
            ctpPr = ctp.addNewPPr();
            ctSpacing = ctpPr.addNewSpacing();
            ctSpacing.setAfterLines(BigInteger.valueOf(100));  // 设置图片下方的外填充间距

            // 添加图片插入代码（具体方法可能需要根据你的库或环境来适配）
            run = paragraph.createRun();
            run.addPicture(in, Document.PICTURE_TYPE_JPEG, "", Units.pixelToEMU((int) (width * scaling)), Units.pixelToEMU((int) (height * scaling)));
        }
        XWPFTable table = doc.createTable(item.size() + 1, 5);
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        tblPr.getTblW().setType(STTblWidth.DXA);  // 设置表格宽度单位为 DXA
        tblPr.getTblW().setW(BigInteger.valueOf(9850));  // 设置表格宽度为 98

        XWPFTableRow row = table.getRow(0);
        row.setHeight(500);  // Set height for header row
        List<XWPFTableCell> tableCells = row.getTableCells();
        String[] array = {
                "序号#800",
                "检查项目#2200",
                "检查结果#3000",
                "单位#1200",
                "参考值#1300",
        };

        for (int i = 0; i <= 4; i++) {
            XWPFTableCell cell = tableCells.get(i);
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell.setColor("f0f0f0");

            paragraph = cell.getParagraphArray(0);

            if (i != 2) {
                paragraph.setAlignment(ParagraphAlignment.CENTER);
            } else {
                paragraph.setIndentationLeft(200);
            }

            run = paragraph.createRun();
            run.setFontSize(9);
            run.setFontFamily("Microsoft YaHei");

            String label = array[i].split("#")[0];
            int width = Integer.parseInt(array[i].split("#")[1]);
            run.setText(label);

            CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
            CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
            ctTblWidth.setW(BigInteger.valueOf(width));
        }
        for (int i = 0; i < item.size(); i++) {
            Map map = item.get(i);

            String name = MapUtil.getStr(map, "name");
            String value = MapUtil.getStr(map, "value");
            String unit = MapUtil.getStr(map, "unit");
            unit = (unit == null) ? "" : unit;
            String standard = MapUtil.getStr(map, "standard");
            standard = (standard == null) ? "" : standard;
            String[] temp = {
                    i + 1 + "",
                    name,
                    value,
                    unit,
                    standard
            };

            row = table.getRow(i + 1);
            row.setHeight(500);
            tableCells = row.getTableCells();
            for (int j = 0; j < temp.length; j++) {
                XWPFTableCell cell = tableCells.get(j);
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                paragraph = cell.getParagraphArray(0);
                run = paragraph.createRun();

                run.setFontSize(9);
                run.setFontFamily("Microsoft YaHei");

                if (j != 2) {
                    paragraph.setAlignment(ParagraphAlignment.CENTER);
                    run.setText(temp[j]);
                } else {
                    paragraph.setAlignment(ParagraphAlignment.LEFT);
                    paragraph.setIndentationLeft(200);

                    array = temp[j].split("#");
                    for (int k = 0; k < array.length; k++) {
                        String one = array[k];
                        run.setText(one);
                        if (k < array.length - 1) { // Add line break if not the last element
                            run.addBreak();
                        }
                    }
                }
            }
        }
        paragraph = doc.createParagraph();
        run = paragraph.createRun();
        run.setFontSize(9);
        run.setFontFamily("Microsoft YaHei");
        run.setText("体检医生: " + doctor + "\t\t\t\t\t\t\t日期: " + date);

        ctp = paragraph.getCTP();
        ctpPr = ctp.addNewPPr();
        ctSpacing = ctpPr.addNewSpacing();
        ctSpacing.setBeforeLines(BigInteger.valueOf(100));
        ctSpacing.setAfterLines(BigInteger.valueOf(150));
    }

    public static void createCustomerInfo(XWPFDocument doc, HashMap param) {
        XWPFParagraph paragraph = doc.createParagraph();
        XWPFRun run = paragraph.createRun();

        run.setFontSize(14);
        run.setFontFamily("Microsoft YaHei");
        run.setText("体检人信息");
        CTP ctp = paragraph.getCTP(); // Get the underlying XML representation of the paragraph
        CTPPr ctpPr = ctp.addNewPPr(); // Get the paragraph properties
        CTSpacing ctSpacing = ctpPr.addNewSpacing(); // Add spacing properties to the paragraph

        ctSpacing.setBeforeLines(BigInteger.valueOf(200)); // Space before the paragraph
        ctSpacing.setAfterLines(BigInteger.valueOf(100));  // Space after the paragraph

        // Create a new table with 4 rows and 6 columns
        XWPFTable table = doc.createTable(4, 6);

        CTTblPr tblPr = table.getCTTbl().getTblPr();  // Get the table properties
        tblPr.getTblW().setType(STTblWidth.DXA);      // Set the width type to DXA (twips)
        tblPr.getTblW().setW(BigInteger.valueOf(9850)); // Set the table width to 9850 twips (roughly 6.8 inches)

        XWPFTableRow row = table.getRow(0);  // Get the first row
        row.setHeight(550);  // Set the row height (in twips, 550 twips is approximately 0.38 inches)

        List<XWPFTableCell> tableCells = row.getTableCells();

        // Set the "姓名" label for the first cell in the row
        XWPFTableCell cell = tableCells.get(0);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("fefefe");  // Set cell background color (light gray)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("姓名");  // Set text content for the cell

        CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();  // Get the cell properties (CTTcPr)
        CTTblWidth ctTblWidth = ctTcPr.addNewTcW();  // Add a new width property (CTTblWidth)
        ctTblWidth.setW(BigInteger.valueOf(1500));  // Set the width of the column (1500 twips)

        cell = tableCells.get(1);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph of the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "name"));  // Set the text to the value from the map ("name")

        cell = tableCells.get(2);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("f0f0fe");  // Set cell background color (light color, you can adjust this)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("性别");  // Set the text to "性别" (Gender)

        ctTcPr = cell.getCTTc().addNewTcPr();  // Get the cell properties (CTTcPr)
        ctTblWidth = ctTcPr.addNewTcW();  // Add a new width property (CTTblWidth)
        ctTblWidth.setW(BigInteger.valueOf(1500));  // Set the width of the column (1500 twips)

        cell = tableCells.get(3);  // Get the fourth cell (index 3)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "sex"));  // Set the text to the value from the map ("sex")

        // Set column width for the cell
        ctTcPr = cell.getCTTc().addNewTcPr();  // Access the cell properties (CTTcPr)
        ctTblWidth = ctTcPr.addNewTcW();  // Add new width property (CTTblWidth)
        ctTblWidth.setW(BigInteger.valueOf(1200));  // Set column width to 1200 twips (approx. 0.83 inches)

        cell = tableCells.get(4);  // Get the fifth cell (index 4)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("f0f0f0");  // Set background color of the cell (light gray)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("出生日期");  // Set the text content to "出生日期" (Date of Birth)
        ctTcPr = cell.getCTTc().addNewTcPr();  // Access the cell properties (CTTcPr)
        ctTblWidth = ctTcPr.addNewTcW();  // Add new width property (CTTblWidth)
        ctTblWidth.setW(BigInteger.valueOf(1500));  // Set column width to 1500 twips (approx. 1.04 inches)

        cell = tableCells.get(5);  // Access the sixth cell (index 5)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "birthday"));  // Set the text content to the "birthday" value from the map
        row = table.getRow(1);  // Access the second row (index 1)
        row.setHeight(550);  // Set the row height to 550
        tableCells = row.getTableCells();  // Get the cells for the second row

        // Set "电话" (Phone Number) Label
        cell = tableCells.get(0);  // Get the first cell (index 0)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("fefefe");  // Set background color to light gray (fefefe)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("电话");  // Set the text content to "电话" (Phone Number)

        cell = tableCells.get(1);  // Get the second cell (index 1)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the second cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "tel"));  // Set the text content to the value of "tel" from the map

        // Set "年龄" (Age) Label
        cell = tableCells.get(2);  // Access the third cell (index 2)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("fefefe");  // Set background color to light gray (fefefe)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("年龄");  // Set the text content to "年龄" (Age)

        cell = tableCells.get(3);  // Access the fourth cell (index 3)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the fourth cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "age"));  // Set the text content to the value of "age" from the map

        cell = tableCells.get(4);  // Access the fifth cell (index 4)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("f0f0f0");  // Set background color to light yellow (f0f0fa)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("体检期");  // Set the text content to "体检期" (Check-up Date)

        cell = tableCells.get(5);  // Access the sixth cell (index 5)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(MapUtil.getStr(param, "date"));  // Set the text content to the value of "date" from the map
        row = table.getRow(2);  // Access the third row (index 2)
        row.setHeight(550);  // Set the height of the row to 550
        tableCells = row.getTableCells();  // Get the cells of the third row

        cell = tableCells.get(0);  // Access the first cell (index 0)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("f0f0f0");  // Set background color to light gray (fefefe)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("单位名称");  // Set the text content to "单位名称" (Company Name)
        cell = tableCells.get(1);  // Access the second cell (index 1)
        cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);  // Set merge value to RESTART for the first cell

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.LEFT);  // Set paragraph alignment to left

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText((String) param.get("company"));  // Set the text content to the "company" value from the param map

        for (int i = 2; i <= 5; i++) {
            cell = tableCells.get(i);  // Access each subsequent cell
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);  // Set merge value to CONTINUE for the next cells
        }

        row = table.getRow(3);  // Access the fourth row (index 3)
        row.setHeight(600);  // Set the row height to 600
        tableCells = row.getTableCells();  // Get the cells of the fourth row

        // Set "体检套餐" (Health Checkup Package) Label
        cell = tableCells.get(0);  // Access the first cell (index 0)
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center
        cell.setColor("f0f0f0");  // Set background color to light gray (fefefe)

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.CENTER);  // Set paragraph alignment to center

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText("体检套餐");  // Set the text content to "体检套餐" (Health Checkup Package)
        cell = tableCells.get(1);  // Access the second cell (index 1)
        cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);  // Set merge value to RESTART for the first cell

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  // Set vertical alignment to center

        paragraph = cell.getParagraphArray(0);  // Get the first paragraph in the cell
        paragraph.setAlignment(ParagraphAlignment.LEFT);  // Set paragraph alignment to left

        run = paragraph.createRun();  // Create a run for text
        run.setFontSize(9);  // Set font size to 9
        run.setFontFamily("Microsoft YaHei");  // Set font family to "Microsoft YaHei"
        run.setText(String.valueOf(param.get("goods")));  // Set the text content to the "goods" value from the param map

        for (int i = 2; i <= 5; i++) {
            cell = tableCells.get(i);  // Access each subsequent cell
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);  // Set merge value to CONTINUE for the next cells
        }

    }

    public XWPFDocument createReport(HashMap map) throws Exception {
        // 创建一个新的文档
        XWPFDocument doc = new XWPFDocument();

        // 设置文档的页边距
        CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
        CTPageMar pageMar = sectPr.addNewPgMar();
        pageMar.setLeft(BigInteger.valueOf(1200));
        pageMar.setRight(BigInteger.valueOf(1200));
        pageMar.setTop(BigInteger.valueOf(1000));
        pageMar.setBottom(BigInteger.valueOf(1000));

        // 设置页脚显示页数
        XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
        XWPFParagraph paragraph = footer.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);
        paragraph.getCTP().addNewFldSimple().setInstr("PAGE * MERGEFORMAT");
        paragraph.createRun();

        String uuid = MapUtil.getStr(map, "uuid");
        String name = MapUtil.getStr(map, "name");
        String sex = MapUtil.getStr(map, "sex");
        String tel = MapUtil.getStr(map, "tel");
        String birthday = MapUtil.getStr(map, "birthday");
        String age = MapUtil.getStr(map, "age");
        String company = MapUtil.getStr(map, "company");
        String date = MapUtil.getStr(map, "date");
        String goods = MapUtil.getStr(map, "goods");
        List<Map> checkup = MapUtil.get(map, "checkup", List.class);
        List<Map> result = MapUtil.get(map, "result", List.class);

        // Create a parameter map using HashMap
        HashMap<String, Object> param = new HashMap<String, Object>() {{
            put("uuid", uuid);  // Add "uuid" to the map
            put("item", new ArrayList<HashMap<String, Object>>() {{
                add(new HashMap<String, Object>() {{
                    put("label", "姓名:");  // Label for name
                    put("value", name);    // Value for name
                }});

                add(new HashMap<String, Object>() {{
                    put("label", "性别:");  // Label for gender
                    put("value", sex);     // Value for gender
                }});

                add(new HashMap<String, Object>() {{
                    put("label", "公司:");  // Label for company
                    put("value", company); // Value for company
                }});

                add(new HashMap<String, Object>() {{
                    put("label", "日期:");  // Label for date
                    put("value", date);    // Value for date
                }});
            }});

            put("name", name);  // Add "name" to the map
            put("sex", sex);// Add "sex" to the map
            put("birthday", birthday);  // Add "birthday" to the map
            put("age", age);              // Add "age" to the map
            put("tel", tel);              // Add "tel" to the map
            put("date", date);            // Add "date" to the map
            put("company", company);      // Add "company" to the map
            put("goods", goods);          // Add "goods" to the map
        }};
        createCover(doc, param);
        createWelcome(doc, param);
        createCustomerInfo(doc, param);

        createCheckup(doc, checkup);
        result.forEach(one -> {
            String template = MapUtil.getStr(one, "template");
            if ("模版1".equals(template)) {
                try {
                    createCheckupResultByTemplate_1(doc, one);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } else if ("模版二".equals(template)) {
                try {
                    createCheckupResultByTemplate_2(doc, one);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        return doc;
    }
}
